package com.itaming.lycheeframework.support.utils;

import lombok.experimental.UtilityClass;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.FileUrlResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Resource工具类
 *
 * @author A.Ming
 */
@UtilityClass
public class ResourceUtil extends ResourceUtils {

    /**
     * 正则
     */
    public static final String CLASSPATH_REGEX = "^classpath\\*?:.+$";

    /**
     * 资源模式解析器
     */
    public static final ResourcePatternResolver RESOURCE_PATTERN_RESOLVER = new PathMatchingResourcePatternResolver();

    /**
     * 获取资源
     * <p>
     * 支持以下协议：
     * <pre>
     * - http:
     * - https:
     * - ftp:
     * - file:
     * - classpath:
     * - classpath*:
     * - C:\path\to\file
     * - /path/to/file
     * </pre>
     *
     * @param resourceLocation 资源路径
     * @return 资源
     */
    public static Resource getResource(String resourceLocation) {
        Assert.notNull(resourceLocation, "Resource location must not be null");

        // classpath:, classpath*:
        if (resourceLocation.startsWith(CLASSPATH_REGEX)) {
            Resource[] resources = getResources(resourceLocation);
            if (ArrayUtil.isEmpty(resources)) {
                throw new IllegalArgumentException("No resource found for location: " + resourceLocation);
            }
            return resources[0];
        }

        try {
            // http:, https:, ftp:, file:
            URL url = new URL(resourceLocation);
            return isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url);
        } catch (MalformedURLException e) {
            // disk file
            File file = new File(resourceLocation);
            if (!file.exists()) {
                throw new IllegalArgumentException("No resource found for location: " + resourceLocation);
            }
            return new FileSystemResource(file);
        }
    }

    /**
     * 获取资源
     *
     * @param resourceLocation 资源路径
     * @return 资源数组
     */
    public static Resource[] getResources(String resourceLocation) {
        try {
            return RESOURCE_PATTERN_RESOLVER.getResources(resourceLocation);
        } catch (IOException e) {
            throw new IllegalArgumentException("Could not resolve resource location: " + resourceLocation, e);
        }
    }

}
